package foodmaterial.filter;

import foodmaterial.dao.PermissionDao;
import foodmaterial.entity.SysUrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class CustomizeFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Autowired
    private PermissionDao dao;

    private static volatile Map<String, String[]> permissionMap = null ;

    private byte[] lock = new byte[0] ;

    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        String requestUrl = ((FilterInvocation) o).getRequestUrl();//获取请求地址
        //具体请求地址所需的权限
        if (permissionMap == null) {
            synchronized (lock) {
                if (permissionMap == null) {
                    permissionMap = new HashMap<>() ;
                    List<SysUrl> list = dao.selectUrl() ;
                    Map<String,List<SysUrl>> map = list.stream().collect(Collectors.groupingBy(SysUrl::getUrl));
                    map.forEach((k,v) -> {
                        String[] codes = new String[v.size()] ;
                        for (int i = 0 ; i < v.size() ; i++) {
                            codes[i] = v.get(i).getPermissionCode();
                        }
                        permissionMap.put(k,codes) ;
                    });
                }
            }
        }
        String[] attributes =  permissionMap.get(requestUrl);
        if(attributes == null){
            //请求路径没有配置权限，表明该请求接口可以任意访问
            return null;
        }
        return SecurityConfig.createList(attributes);
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
